package com.mayisoftware.mayioa.business.plan.impl.controller;

import com.mayisoftware.mayioa.business.personal.api.domain.PersonalSign;
import com.mayisoftware.mayioa.business.personal.api.service.IPersonalSignService;
import com.mayisoftware.mayioa.business.plan.api.domain.*;
import com.mayisoftware.mayioa.business.plan.api.service.*;
import com.mayisoftware.mayioa.common.api.annotation.Log;
import com.mayisoftware.mayioa.common.api.base.AjaxResult;
import com.mayisoftware.mayioa.common.api.enums.BusinessType;
import com.mayisoftware.mayioa.common.impl.utils.ExcelExportUtil;
import com.mayisoftware.mayioa.common.impl.utils.StringUtils;
import com.mayisoftware.mayioa.platform.api.domain.SysDept;
import com.mayisoftware.mayioa.platform.api.domain.SysPost;
import com.mayisoftware.mayioa.platform.api.domain.SysUser;
import com.mayisoftware.mayioa.platform.api.service.ISysDeptService;
import com.mayisoftware.mayioa.platform.api.service.ISysMailService;
import com.mayisoftware.mayioa.platform.api.service.ISysUserService;
import com.mayisoftware.mayioa.platform.impl.util.ShiroUtils;
import com.mayisoftware.mayioa.platform.impl.web.base.BaseController;
import com.mayisoftware.mayioa.platform.impl.web.page.TableDataInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 计划配置
 */
@Controller
@RequestMapping("/plan/config")
public class PlanConfigController extends BaseController
{
    /**
     * 日志对象
     */
    private static final Logger log = LoggerFactory.getLogger(PlanConfigController.class);

    private String prefix = "plan/config";

    @Autowired
    private IPlanConfigService planConfigService;

    @Autowired
    private IPlanConfigDetailService planDetailService;

    @Autowired
    private IPlanClassService planClassService;

    @Autowired
    private IPlanCustomService planCusService;

    @Autowired
    private IPlanArchService planArchService;

    @Autowired
    private IPlanFlowService planFlowService;

    /**
     * 用户报名服务
     */
    @Autowired
    private IPersonalSignService personalSignService;

    @Autowired
    private IPlanConstraintService planConstraintService;

    @Autowired
    private ISysMailService mailService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysDeptService sysDeptService;
    /**
     * 查看计划配置
     */
    @RequiresPermissions("plan:config:view")
    @GetMapping()
    public String planConfig()
    {
        return prefix + "/config";
    }

    /**
     * 新增计划
     */
    @GetMapping("/add")
    public String add(ModelMap mmap)
    {
//        String flag = planConstraintService.checkPlanIsCanEnter(1l,103205l);

        mmap.put("flowList", planFlowService.queryRecordListSucc());
        mmap.put("conditions", planConstraintService.selectPlanConstraintList(new PlanConstraint()));
        return prefix + "/add";
    }

    /**
     * 新增保存计划配置
     */
    @RequiresPermissions("plan:config:add")
    @Log(title = "计划配置管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public AjaxResult addSave(PlanConfig planConfig)
    {
        planConfig.setPlanCfgUpdateUserId(ShiroUtils.getUserId());
        planConfig.setPlanCfgStatus("0");
        return toAjax(planConfigService.insertPlanConfig(planConfig));
    }

    /**
     * 修改计划配置
     */
    @GetMapping("/edit/{planCfgId}")
    public String edit(@PathVariable("planCfgId") Long planCfgId, ModelMap mmap)
    {
        mmap.put("planConfig",planConfigService.selectPlanConfigById(planCfgId));
        mmap.put("flowList", planFlowService.queryRecordListSucc());
        mmap.put("conditions", planConstraintService.selectPlanConstraintByPlanId(planCfgId));
        return prefix + "/edit";
    }

    /**
     * 修改保存计划配置
     */
    @RequiresPermissions("plan:config:edit")
    @Log(title = "计划配置管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public AjaxResult editSave(PlanConfig planConfig)
    {
        planConfig.setPlanCfgUpdateUserId(ShiroUtils.getUserId());
        return toAjax(planConfigService.updatePlanConfig(planConfig));
    }

    @RequiresPermissions("plan:config:remove")
    @Log(title = "计划配置管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        try
        {
            int flag = planDetailService.deletePlanItemByCfgIds(ids);
            return toAjax(planConfigService.deletePlanConfigByIds(ids));
        }
        catch (Exception e)
        {
            return error(e.getMessage());
        }
    }

    /**
     * 发送计划发布邮件
     * @param planId
     */
    public void sendPlanPublishMail(Integer planId){
        if(planId == null){
            log.error("参数为空.");
            return;
        }
        PlanConfig planConfig = planConfigService.selectPlanConfigById(planId.longValue());
        Integer ancestorDeptId = planConfig.getPlanCfgDeptId();
        List<SysDept> deptList = sysDeptService.selectDeptListByAncestor(ancestorDeptId);
        for(SysDept sysDept : deptList){
            Long deptId = sysDept.getDeptId();
            List<SysUser> userList = userService.selectUserByDeptId(deptId.intValue());
            for(SysUser sysUser : userList){
                sendPlanPublishMail(sysUser, planConfig.getPlanCfgName());
            }
        }
    }

    /**
     * 发送计划发布邮件
     * @param sysUser
     * @param planName
     */
    public void sendPlanPublishMail(SysUser sysUser, String planName){
        if (sysUser == null){
            log.error("参数为空");
            return;
        }
        String sendto = sysUser.getEmail();
        if(StringUtils.isEmpty(sendto)){
            log.info("email is null or empty."+sysUser.getUserId());
            return;
        }
        String title = "【mayioa】系统通知";
        String content = "计划已发布.计划名称："+planName;
        mailService.insertMail(sendto, title, content);
    }

    @RequiresPermissions("plan:config:publish")
    @Log(title = "计划配置管理", businessType = BusinessType.PUBLISH)
    @PostMapping("/publish")
    @ResponseBody
    public AjaxResult publish(String id)
    {
        try
        {
            PlanConfig planConfig = new PlanConfig();
            planConfig.setPlanCfgUpdateUserId(ShiroUtils.getUserId());
            planConfig.setPlanCfgId(Integer.valueOf(id));
            planConfig.setPlanCfgStatus("1");

            // 生成计划模板，返回模板路径
            planConfig.setPlanCfgTplPath(createPlanTemplate(id));
            int rowNum = planConfigService.publishPlanConfig(planConfig);
            sendPlanPublishMail(Integer.valueOf(id));
            return toAjax(rowNum);
        }
        catch (Exception e)
        {
            log.error("发布异常", e);
            return error(e.getMessage());
        }
    }

    @RequiresPermissions("plan:config:publish")
    @Log(title = "计划配置管理", businessType = BusinessType.PUBLISH)
    @PostMapping("/cancel")
    @ResponseBody
    public AjaxResult cancel(String id)
    {
        try
        {
            boolean flag = personalSignService.isPlanJoined(Integer.valueOf(id));
            if(flag)
            {
                return error("已被报名的计划不能撤消");
            }

            PlanConfig planConfig = new PlanConfig();
            planConfig.setPlanCfgUpdateUserId(ShiroUtils.getUserId());
            planConfig.setPlanCfgId(Integer.valueOf(id));
            planConfig.setPlanCfgStatus("0");

            return toAjax(planConfigService.publishPlanConfig(planConfig));
        }
        catch (Exception e)
        {
            return error(e.getMessage());
        }
    }

    private String createPlanTemplate(String id)
    {
        Map<String, String> headMap = new LinkedHashMap<String, String>();
        headMap.put("seq", "序号");
        headMap.put("jobNo", "工号");
        headMap.put("userName", "姓名");
        headMap.put("costCenter", "成本中心");
        headMap.put("sex", "性别");
        headMap.put("hwLevel", "华为职级");
        headMap.put("mayisoftwarePost", "蚂蚁职位");
        headMap.put("coopMode", "合作模式");
        headMap.put("joinTime", "入职日期");
        headMap.put("workingTime", "工作日期");
        headMap.put("school", "毕业院校");
        headMap.put("education", "学历");
        headMap.put("is211", "是否211");
        headMap.put("email", "邮箱");
        headMap.put("telephone", "电话");
        headMap.put("directLeader", "直接上级");
        headMap.put("projectRole", "项目组角色");
        headMap.put("region", "地区");

        // 绩效最大分数
        Integer archMax = planArchService.selectPlanAchMaxScore();

        List<PlanDetailConfig> planItemList = planDetailService.selectPlanItemByPlanId(Long.valueOf(id));
        for (PlanDetailConfig item : planItemList)
        {
            // 3-绩效
            if(item.getPlanCfgItemType().toString().equals("3"))
            {
                headMap.put("achievement", "绩效\n" + item.getPlanCfgItemName() + "\n(" + archMax + "分)");
            }
            // 2-自定义
            else if(item.getPlanCfgItemType().toString().equals("2"))
            {
                PlanCustom custom = planCusService.selectPlanCusById(item.getPlanCfgItemId().longValue());
                headMap.put("custom" + item.getPlanCfgItemId(), "自定义\n" + item.getPlanCfgItemName() + "\n(" + custom.getPlanCusTotalScore() + "分)");
            }
            // 1-课程
            else
            {
                PlanClass pc = planClassService.selectPlanClassById(item.getPlanCfgItemId().longValue());
                headMap.put("course" + item.getPlanCfgItemId(), "课程\n" + item.getPlanCfgItemName() + "\n(" + pc.getPlanClassTotalScore() + "分)");
            }
        }

        PlanConfig planConfig = planConfigService.selectPlanConfigById(Long.valueOf(id));

        return ExcelExportUtil.createExcelTemplate(planConfig.getPlanCfgName(),headMap,null);
    }

    /**
     * 校验计划配置名称唯一
     */
    @PostMapping("/checkPlanCfgNameUnique")
    @ResponseBody
    public String checkPlanCfgNameUnique(PlanConfig planConfig)
    {
        return planConfigService.checkPlanCfgNameUnique(planConfig);
    }

    /**
     * 查询计划详细
     */
    @RequiresPermissions("plan:config:detail")
    @GetMapping("/detail/{planCfgId}")
    public String detail(@PathVariable("planCfgId") Long planCfgId, ModelMap mmap)
    {
        mmap.put("planConfig",planConfigService.selectPlanConfigById(planCfgId));
        mmap.put("planConfigList",planConfigService.selectPlanConfigAll());
        return "plan/config/detail/detail";
    }

    /**
     * 查询计划约束
     */
    @RequiresPermissions("plan:config:constraint")
    @GetMapping("/constraint/{planCfgId}")
    public String constraint(@PathVariable("planCfgId") Long planCfgId, ModelMap mmap)
    {
        mmap.put("planConfig",planConfigService.selectPlanConfigById(planCfgId));
        mmap.put("planConfigList",planConfigService.selectPlanConfigAll());
        return "plan/config/constraint/detail";
    }

    /**
     * 查询计划配置列表
     */
    @RequiresPermissions("plan:config:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(PlanConfig planConfig)
    {
        startPage();
        List<PlanConfig> list = planConfigService.selectPlanConfigList(planConfig);
        return getDataTable(list);
    }

    @RequiresPermissions("plan:config:download")
    @Log(title = "计划配置管理", businessType = BusinessType.DOWNLOAD)
    @PostMapping("/download")
    @ResponseBody
    public AjaxResult downloadTemplate(String id)
    {
        PlanConfig planConfig = planConfigService.selectPlanConfigById(Long.valueOf(id));

        if (StringUtils.isEmpty(planConfig.getPlanCfgTplPath())){
            return  error("计划模板文件不存在");
        }

        return success(planConfig.getPlanCfgTplPath().replace("\\","/"));
    }

}
